#title: 文件池
#author:zozoh(zozohtnt@gmail.com)
#index:0,1
----------------------------------------------------------------------------------------
什么是文件池

    如果大家写一些稍微复杂的应用，可能或多或少的会使用一下临时文件。或者
    希望能有一个目录，保存用户上传的文件。你的用法可能有下面两种：

     * 文件不能超过一定数量，超过了自动删除旧的
     * 文件永远保存，除非程序主动删除

    对于网络应用，处理用户上传的文件，有一种比较常用的做法是：
     
     * 把文件的索引以及一些信息记录在数据库里
     * 把文件内容记录在磁盘里

    而 Nutz 的文件池，就是为上述这些场景设计的。

----------------------------------------------------------------------------------------
怎么使用文件池

    对于文件池，它有一个接口 '{#A0A;*org.nutz.filepool.FilePool}' 以及
    一个简单的实现 '{#A0A;*org.nutz.filepool.NutFilePool}'。当然，你可以
    根据需要实现自己的特殊规则的文件池实现类。

    创建文件池
        {{{<Java>
        // 将目录 ~/tmp/myfiles 作为一个文件池的根目录，里面最多同时有2000个文件
        FilePool pool = new NutFilePool("~/tmp/myfiles", 2000);

        // 将目录 ~/tmp/myfiles 作为一个文件池的根目录，里面不限文件
        FilePool pool = new NutFilePool("~/tmp/myfiles");
        // 相当于 FilePool pool = new NutFilePool("~/tmp/myfiles", 0);
        }}}

    在池中创建一个文件
        {{{<Java>
        File f = pool.createFile(".png");  // 该文件本句之后，已经被创建
        // TODO 为这个文件写入内容
        }}}

        实际上， NutFilePool 会将你的 id （一个 Long 值）以及后缀变成如下形式的文件路径:
        {{{
        ~/tmp/myfiles/00/00/00/00/00/00/00/EF.png
        }}}
        也就是说，你传入的 Long 值会先变成字符串 '00000000000000EF'， 然后每两位字符加入
        一个 '/'，最后拼上 ".png" 就成为你这个文件在池中的路径了。

        这样做的好处是，你只要在数据库记录一个自增的 ID，就能知道在池中对应文件的路径。
        同样，如果你知道了在池中对应文件的路径，你也能知道在数据库中记录的 ID。这个特性
        有时候是很有用的。

        文件池会维护一个自增的 id， 每当成功创建一个文件后，它就会自加。

        {#00A;*补充说明:}
        NutFilePool 这个实现非常简单，没有考虑到集群，即多台主机共用一个文件池的问题。但是
        如果在一台主机内，虽然它没用用线程同步锁，但是线程安全也不太会是问题，因为是直接一句
        自加，即使是多线程竞争也不会出问题的。

        了解了这个之后，之后的操作就都顺理成章了 ^_^

    从池中获取一个文件
        {{{<Java>
        File f = pool.getFile(239, ".png");  // 如果文件不存在，将返回 null
        }}}

    从池中获取一个文件，如果不存在，创建它
        {{{<Java>
        File f = pool.returnFile(239, ".png");  
        }}}

    从池中删除一个文件
        {{{<Java>
        File f = pool.removeFile(239, ".png");
        }}}
    
    判断池中是否存在一个文件
        {{{<Java>
        boolean exists = pool.hasFile(239, ".png");
        }}}

    看看当前池中最大的文件 ID
        {{{<Java>
        long maxId = pool.current();
        }}}

    看看某一个池中的文件的 ID 为多少
        {{{<Java>
        File f = pool.getFile(239, ".png");
        long fId = pool.getFileId(f, ".png");
        // fId should be 239
        }}}

    清除池中所有文件
        {{{<Java>
        pool.clear();
        }}}
        
----------------------------------------------------------------------------------------
在 Ioc 中使用
    
    文件池当然可以被任何 Ioc 容器管理，下面我们以 Nutz.Ioc 的 JSON 配置方式来举例:
    {{{<Json>
    {
        pool : {
            type : 'org.nutz.filepool.NutFilePool',
            args : ['~/tmp/files', 2000]
        }
    }
    }}}
    我想熟悉 Spring 或者 Guice 的朋友，怎么配置自然不用我多嘴了吧 











